Intel systems with more than 8 CPUs require that the APIC is configured
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 23 Nov 2005 11:11:05 +0000 (12:11 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 23 Nov 2005 11:11:05 +0000 (12:11 +0100)
in clustered mode with the apic=bigsmp kernel parameter. This patch does
the APIC mode selection automatically without needing to manually specify
the kernel paremeter.

(KAF note: I see the patch is also present in Linux 2.6.14.2)

Signed-off-by: Nitin Kamble <nitin.a.kamble@intel.com>
Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
xen/arch/x86/acpi/boot.c
xen/arch/x86/genapic/bigsmp.c
xen/arch/x86/genapic/probe.c
xen/arch/x86/mpparse.c
xen/include/asm-x86/apicdef.h
xen/include/asm-x86/mach-generic/mach_apic.h
xen/include/asm-x86/mpspec.h

index 2d5b82cda43c83d5f3a7c2545c9b1dc36433b7f5..12ead9691c0bce871798601e84773c1c17abc2f8 100644 (file)
@@ -602,7 +602,8 @@ acpi_process_madt(void)
                error = acpi_parse_madt_lapic_entries();
                if (!error) {
                        acpi_lapic = 1;
-
+                       generic_bigsmp_probe();
                        /*
                         * Parse MADT IO-APIC entries
                         */
index 93c00b920861fce490cc5c89a69ae578afdd5a02..61b594a4097794f7fa9c415045014303a4648816 100644 (file)
@@ -45,7 +45,10 @@ static struct dmi_system_id __initdata bigsmp_dmi_table[] = {
 
 static __init int probe_bigsmp(void)
 { 
-       dmi_check_system(bigsmp_dmi_table);
+       if (def_to_bigsmp)
+               dmi_bigsmp = 1;
+       else
+               dmi_check_system(bigsmp_dmi_table);
        return dmi_bigsmp; 
 } 
 
index a3a94fe753e61e5f4862a8613e96419f2d1f3449..cddde7a45986834e8273b0dc9415d387b359923e 100644 (file)
@@ -29,6 +29,25 @@ struct genapic *apic_probe[] __initdata = {
        NULL,
 };
 
+static int cmdline_apic;
+
+void __init generic_bigsmp_probe(void)
+{
+       /*
+        * This routine is used to switch to bigsmp mode when
+        * - There is no apic= option specified by the user
+        * - generic_apic_probe() has choosen apic_default as the sub_arch
+        * - we find more than 8 CPUs in acpi LAPIC listing with xAPIC support
+        */
+
+       if (!cmdline_apic && genapic == &apic_default)
+               if (apic_bigsmp.probe()) {
+                       genapic = &apic_bigsmp;
+                       printk(KERN_INFO "Overriding APIC driver with %s\n",
+                              genapic->name);
+               }
+}
+
 static void __init genapic_apic_force(char *str)
 {
        int i;
@@ -41,7 +60,7 @@ custom_param("apic", genapic_apic_force);
 void __init generic_apic_probe(void) 
 { 
        int i;
-       int changed = (genapic != NULL);
+       int changed = cmdline_apic = (genapic != NULL);
 
        for (i = 0; !changed && apic_probe[i]; i++) { 
                if (apic_probe[i]->probe()) {
index 268c9cdf71db08910f529eebb50052b4e04e3fca..91355de55e0db9aeda93416d2b1662572bd2f18c 100644 (file)
@@ -63,6 +63,8 @@ int nr_ioapics;
 int pic_mode;
 unsigned long mp_lapic_addr;
 
+unsigned int def_to_bigsmp;
+
 /* Processor that is doing the boot up */
 unsigned int boot_cpu_physical_apicid = -1U;
 unsigned int boot_cpu_logical_apicid = -1U;
@@ -213,6 +215,13 @@ void __init MP_processor_info (struct mpc_config_processor *m)
                ver = 0x10;
        }
        apic_version[m->mpc_apicid] = ver;
+       if ((num_processors > 8) &&
+           APIC_XAPIC(ver) &&
+           (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL))
+               def_to_bigsmp = 1;
+       else
+               def_to_bigsmp = 0;
+
        bios_cpu_apicid[num_processors - 1] = m->mpc_apicid;
 }
 
index 5357707cede84c46234698dbe17d3175b91cc7d7..93ae434496b53cb460a50e0ba30b9888ed8324ff 100644 (file)
@@ -16,6 +16,7 @@
 #define                        GET_APIC_VERSION(x)     ((x)&0xFF)
 #define                        GET_APIC_MAXLVT(x)      (((x)>>16)&0xFF)
 #define                        APIC_INTEGRATED(x)      ((x)&0xF0)
+#define                        APIC_XAPIC(x)           ((x) >= 0x14)
 #define                APIC_TASKPRI    0x80
 #define                        APIC_TPRI_MASK          0xFF
 #define                APIC_ARBPRI     0x90
index b13767a4e9345211eaa68a5c1439ee59f82e6cdc..d9dc039da94a3a12b4902d477bb48c0e6d8f205e 100644 (file)
@@ -28,4 +28,6 @@
 #define enable_apic_mode (genapic->enable_apic_mode)
 #define phys_pkg_id (genapic->phys_pkg_id)
 
+extern void generic_bigsmp_probe(void);
+
 #endif /* __ASM_MACH_APIC_H */
index 7add5271736b0f1f3a9db2243009075c61e505fd..1e3d48a470dda13378482037b0f9995e52547e29 100644 (file)
@@ -11,6 +11,7 @@ extern int mp_bus_id_to_local [MAX_MP_BUSSES];
 extern int quad_local_to_mp_bus_id [NR_CPUS/4][4];
 extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES];
 
+extern unsigned int def_to_bigsmp;
 extern unsigned int boot_cpu_physical_apicid;
 extern int smp_found_config;
 extern void find_smp_config (void);